package com.briup.myblog.service.impl;

import com.briup.myblog.bean.basic.Category;
import com.briup.myblog.bean.ext.ArticleExt;
import com.briup.myblog.bean.ext.CategoryExt;
import com.briup.myblog.bean.ext.CommentExt;
import com.briup.myblog.dao.basic.ArticleMapper;
import com.briup.myblog.dao.basic.CategoryMapper;
import com.briup.myblog.dao.ext.ArticleExtMapper;
import com.briup.myblog.dao.ext.CategoryExtMapper;
import com.briup.myblog.dao.ext.CommentExtMapper;
import com.briup.myblog.exception.CustomerException;
import com.briup.myblog.service.ICategoryService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class CategoryServiceImpl implements ICategoryService {
    @Autowired
    private CategoryMapper categoryMapper;
    @Autowired
    private CategoryExtMapper categoryExtMapper;
    @Autowired
    private ArticleExtMapper articleExtMapper;
    @Autowired
    private ArticleServiceImpl articleService;


    //批量删除资讯栏目
    @Override
    public void CategoryBatchDeleteByIds(Integer[] ids) {
        int index = 0; //index是noCategory的,不存在栏目
        int[] noCategory = null; //保存资讯栏目不存在的输入id
        Category category;
        if (ids.length == 0) {
            throw new CustomerException("没有选择");
        }
        /**
         * 对ids进行排序，从大到小排序
         * 因为栏目id是自增的，所有从前端插入数据时数据库中id小的会一直在上面
         * 但是在ids接收前端传来的数据时可能是小的在前
         * 按这样删除会导致（存在id大的数据是小的子栏目时）删除了小的那到大的时候会在根据id删除方法中抛出异常
         */
        Arrays.sort(ids, Collections.reverseOrder()); //排序，大到小
        for (int i = 0; i < ids.length; i++) {
            if (ids[i] <= 0) {
                throw new CustomerException("输入的id有误,不能小于等于0");
            }
            //查找是否栏目存在
            category = categoryMapper.selectByPrimaryKey(ids[i]);
            //栏目不存在
            if (category == null) {
                noCategory[index++] = ids[i];
            }
        }
        if (noCategory == null) {
            for (int i = 0; i < ids.length; i++) {
                //调用根据id删除栏目的方法
                categoryDeleteById(ids[i]);
            }
        } else {
            throw new CustomerException("id为" + Arrays.toString(noCategory) + "的资讯栏目不存在");
        }
    }

    //根据id删除栏目
    @Override
    public void categoryDeleteById(Integer id) {
        /**
         * 删除栏目信息需要删除栏目下对应的所有的咨询信息以及咨询信息对应的评论信息
         * 如果栏目作为父栏目使用，需要实现将该栏目对应的所有子栏目全部删除
         */
        //查找子栏目
        findChild(id);
    }

    //查找子栏目并删除栏目、资讯、评论
    @Override
    public void findChild(Integer id) {
        //第一次从controller传来的id应当先判断是否存在，查找子栏目，findChild();
        //查找父栏目的id为传进来的id的栏目
        List<CategoryExt> categoryList = categoryExtMapper.selectByParentId(id);
        if (categoryList.size() != 0) {
            //存在子栏目，再查找当前子栏目是否还存在子栏目
            for (int i = 0; i < categoryList.size(); i++) {
                //递归查找当前子栏目是否存在子栏目
                findChild(categoryList.get(i).getCategoryId());
            }
        }
        //不管是否为父栏目都删除相应的资讯和评论，先评论表，再删资讯表，后是删栏目表
        //判断是否有资讯，一个栏目可以有多个资讯
        List<ArticleExt> articleExtList = articleExtMapper.selectByCategoryId(id);
        if (articleExtList.size() != 0) {
            for (int i = 0; i < articleExtList.size(); i++) {
                int articleId = articleExtList.get(i).getArticleId();
                //转到资讯信息根据id删除
                articleService.deleteArticleById(articleId);
            }
        }
        //删除栏目
        int numCategory = categoryMapper.deleteByPrimaryKey(id);
        if (numCategory == 0) {
            throw new CustomerException("删除失败(栏目)，id为" + id);
        }
    }

    //查询所有资讯栏目
    @Override
    public List<CategoryExt> findCategoryAll() {
        List<CategoryExt> list = categoryExtMapper.selectCategoryAll();
        if (list == null) {
            throw new CustomerException("没有资讯");
        }
        // 按照排序号正序,排序号中可以有 null 值
        list = list.stream().sorted(Comparator.comparing(CategoryExt::getCategoryOrder,
                Comparator.nullsFirst(Integer::compareTo)))
                .collect(Collectors.toList());
        return list;
    }

    //查询所有资讯栏目并分页
    @Override
    public PageInfo<CategoryExt> findCategoryAllToPage(Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        List<CategoryExt> list = categoryExtMapper.selectCategoryAll();
        if (list == null) {
            throw new CustomerException("没有资讯");
        }
        /**
         * 按照排序号正序,排序号中可以有 null 值
         * Stream流实现排序功能
         * nullsFirst是指将unll值放到前面
         */
        list = list.stream().sorted(Comparator.comparing(CategoryExt::getCategoryOrder,
                Comparator.nullsFirst(Integer::compareTo)))
                .collect(Collectors.toList());
        PageInfo<CategoryExt> pageInfo = new PageInfo<>(list);
        return pageInfo;
    }

    //保存栏目
    @Override
    public void saveCategory(String categoryDescription, String categoryName, Integer categoryOrder, Integer categoryParentId) {
        int num = 0;

        CategoryExt category1 = categoryExtMapper.findCategoryName(categoryName);
        if(category1 != null) {
            throw new CustomerException("栏目名称已存在");
        }

        if (categoryParentId == null) {
            num = categoryExtMapper.insertNoParent(categoryDescription, categoryName, categoryOrder);
        } else {
            Category category = categoryMapper.selectByPrimaryKey(categoryParentId);
            if (category == null) {
                throw new CustomerException("请检查父级栏目id是否存在");
            }
            num = categoryExtMapper.insert(categoryDescription, categoryName, categoryOrder, categoryParentId);
        }

        if (num == 0) {
            throw new CustomerException("保存失败");
        }
    }

    //更行栏目信息
    @Override
    public void updateCategory(Category category) {
        int n = category.getCategoryId();

        String categoryName = category.getCategoryName();
        CategoryExt category1 = categoryExtMapper.findCategoryName1(categoryName,n);

        if(category1 != null) {
            throw new CustomerException("栏目名称已存在");
        }
        int num = categoryMapper.updateByPrimaryKey(category);
        if (num == 0) {
            throw new CustomerException("更行栏目失败");
        }
    }
}
